import { _decorator, Camera, color, Component, Event, Label, Node, Prefab, randomRangeInt, Sprite, SpriteFrame, Tween, tween, UIOpacity, v2, Vec2, Vec3 } from 'cc';
import { UIManager, Panel } from '../../Scripts/Framework/Managers/UIManager';
import { InGameManager } from './Managers/InGameManager';
import { ProjectEventManager, ProjectEvent } from '../../Scripts/Framework/Managers/ProjectEventManager';
import Banner from '../../Scripts/Banner';
import { Adorn } from './Items/Adorn';
import { BundleManager } from '../../Scripts/Framework/Managers/BundleManager';
import { EasingType } from '../../Scripts/Framework/Utils/TweenUtil';
import { PoolManager } from '../../Scripts/Framework/Managers/PoolManager';
import NodeUtil from '../../Scripts/Framework/Utils/NodeUtil';
import { GameDataManager } from '../../MainPack/Scripts/GameDataManager';
const { ccclass, property } = _decorator;

@ccclass('GameUI')
export class GameUI extends Component {

    private static instance: GameUI;
    public static get Instance(): GameUI {
        return this.instance;
    }

    @property(Node)
    controlUI: Node;

    @property(Node)
    packUI: Node;

    @property(Node)
    winUI: Node;

    @property(Node)
    failUI: Node;

    @property(Node)
    finishUI: Node;

    @property(Node)
    adornUI: Node;

    @property(Node)
    endModels: Node;

    @property(Node)
    dmgUI: Node;

    @property(Prefab)
    dmgPrefab: Prefab;

    isFinish = false;
    curAdorn: Adorn;

    protected onLoad(): void {
        GameUI.instance = this;
        ProjectEventManager.emit(ProjectEvent.游戏开始);
    }

    start() {

    }

    update(deltaTime: number) {

    }

    Win() {
        if (this.isFinish) return;
        let data = GameDataManager.Instance.getArrayData("TaskRequires");
        data[0]++;
        data[2]++;
        GameDataManager.Instance.setArrayData("TaskRequires", data);
        let coin = GameDataManager.Instance.getNumberData("Coin");
        let delta = 500 * ((51 - InGameManager.Instance.allGamers) / 50);
        coin += delta;
        GameDataManager.Instance.setNumberData("Coin", coin);
        this.winUI.children[2].children[0].getComponent(Label).string = `+${delta}`;
        this.isFinish = true;
        this.controlUI.active = false;
        this.packUI.active = false;
        this.winUI.active = true;
        ProjectEventManager.emit(ProjectEvent.游戏结束);
        let num = 5;
        let label = this.winUI.children[4].children[2].getComponent(Label);
        label.string = `${num}秒后结算……`;
        this.schedule(() => {
            num--;
            label.string = `${num}秒后结算……`;
            if (num == 0) this.Finish();
        }, 1, 4);
        this.InitEnd();
    }

    Fail() {
        if (this.isFinish) return;
        let data = GameDataManager.Instance.getArrayData("TaskRequires");
        data[0]++;
        GameDataManager.Instance.setArrayData("TaskRequires", data);
        let coin = GameDataManager.Instance.getNumberData("Coin");
        let delta = 500 * ((51 - InGameManager.Instance.allGamers) / 50);
        coin += delta;
        GameDataManager.Instance.setNumberData("Coin", coin);
        this.failUI.children[2].children[0].getComponent(Label).string = `+${delta}`;
        this.isFinish = true;
        this.controlUI.active = false;
        this.packUI.active = false;
        this.failUI.children[2].children[1].getComponent(Label).string = `第${InGameManager.Instance.allGamers}名`;
        this.failUI.active = true;
        ProjectEventManager.emit(ProjectEvent.游戏结束);
        let num = 5;
        let label = this.failUI.children[4].children[2].getComponent(Label);
        label.string = `${num}秒后结算……`;
        this.schedule(() => {
            num--;
            label.string = `${num}秒后结算……`;
            if (num == 0) this.Finish();
        }, 1, 4);
        this.InitEnd();
    }

    Finish() {
        this.finishUI.active = true;
        let layout = this.finishUI.children[0].children[0];
        for (let i = 0; i < layout.children.length; i++) {
            const element = layout.children[i].children[0].getComponent(Label);
            element.string = InGameManager.Instance.endData[i].toFixed();
        }
    }

    Reset() {
        UIManager.ShowPanel(Panel.LoadingPanel, ["PUBG", "Game"]);
    }

    Back() {
        UIManager.ShowPanel(Panel.LoadingPanel, ["MainPack", "Lobby"]);
    }

    Auto(event: Event) {
        let target: Node = event.target;
        let num = target.getSiblingIndex();
        let controlUI: any = this.controlUI.getComponent("ControlUI");
        if (num == 0) {
            controlUI.isAuto = false;
            target.parent.parent.parent.active = false;
            controlUI.autoShoot.progress = 0;
            controlUI.autoShoot.getComponent(Sprite).color = color(255, 255, 255);
            controlUI.autoLabel.string = "手动开火";
        }
        else {
            Banner.Instance.ShowVideoAd(() => {
                controlUI.isAuto = true;
                target.parent.parent.parent.active = false;
                controlUI.autoShoot.progress = 1;
                controlUI.autoShoot.getComponent(Sprite).color = color(255, 255, 0);
                controlUI.autoLabel.string = "自动开火";
            })
        }
    }

    AdornShow(adorn: Adorn) {
        this.curAdorn = adorn;
        this.adornUI.active = true;
        let target = this.adornUI.children[1];
        target.setScale(Vec3.ZERO);
        Tween.stopAllByTarget(target);
        tween(target)
            .to(1, { scale: Vec3.ONE }, { easing: EasingType.backOut })
            .start();
        let sprite = target.children[1].children[0].getComponent(Sprite);
        BundleManager.GetBundle("MainPack").load(adorn.sfUrl, SpriteFrame, (err, data) => { sprite.spriteFrame = data; });
    }

    AdornClose() {
        this.adornUI.active = false;
        PoolManager.PutItem(this.curAdorn);
        this.curAdorn = null;
    }

    AdornGet() {
        let x = this;
        Banner.Instance.ShowVideoAd(() => {
            let data = GameDataManager.Instance.getArrayData<number[]>("AllSkin");
            data[x.curAdorn.type][x.curAdorn.num] = 1;
            GameDataManager.Instance.setArrayData("AllSkin", data);
            let data2 = GameDataManager.Instance.getArrayData("UseSkin");
            data2[x.curAdorn.type] = x.curAdorn.num;
            GameDataManager.Instance.setArrayData("UseSkin", data2);
            let player = InGameManager.Instance.player.getComponent("PlayerController") as any;
            player.InitModel();
            x.AdornClose();
        });
    }

    InitEnd() {
        let data = GameDataManager.Instance.getArrayData("UseSkin");
        let adorns = InGameManager.itemsJson.Adorn;
        let model: Node = PoolManager.GetNodeByPrefab(InGameManager.Instance.gamerPrefabs[data[0]], this.endModels);
        let headwears = NodeUtil.GetNode("toutao", model);
        let wings = NodeUtil.GetNode("chibang", model);
        // let beibao = NodeUtil.GetNode("beibao", model);
        // beibao.active = false;
        if (headwears.children[0]) PoolManager.PutNode(headwears.children[0]);
        if (wings.children[0]) PoolManager.PutNode(wings.children[0]);
        if (data[1] >= 0) {
            let head = adorns[1][data[1]];
            PoolManager.GetNodeByBundle("MainPack", head.prefab, headwears);
        }
        if (data[2] >= 0) {
            let wing = adorns[2][data[2]];
            PoolManager.GetNodeByBundle("MainPack", wing.prefab, wings);
        }
        this.SetLayer(model);
    }

    SetLayer(target: Node) {
        for (let i = 0; i < target.children.length; i++) {
            const element = target.children[i];
            element.layer = 1 << 6;
            if (element.children.length > 0) this.SetLayer(element);
        }
    }

    ShowDmg(num: number, pos: Vec3) {
        let camera = InGameManager.Instance.cameraNode.getComponent(Camera);
        camera.convertToUINode(pos, this.dmgUI, pos);
        let label: Node = PoolManager.GetNodeByPrefab(this.dmgPrefab, this.dmgUI);
        label.setPosition(pos);
        label.getComponent(Label).string = num.toFixed();
        label.setScale(Vec3.ZERO);
        let op = label.getComponent(UIOpacity);
        op.opacity = 255;
        let pos2 = v2();
        Vec2.random(pos2, 50);
        let rPos = pos2.toVec3();
        tween(label)
            .by(0.25, {
                scale: Vec3.ONE,
                position: rPos
            })
            .call(() => {
                tween(op)
                    .to(0.25, { opacity: 0 })
                    .call(() => { PoolManager.PutNode(label); })
                    .start();
            })
            .start();
    }

}